#if !defined(_EL_Struct_)
#define _EL_Struct_

#include <boost/operators.hpp>
#include <src/data/ParticleSet.h>
#include <src/data/WeightsSet.h>
#include <src/miscellaneous/OS_basic.h>

template <class w, class d>
class EL_Struct : 
	private      
		boost::addable< EL_Struct<w,d>          
    ,	boost::subtractable< EL_Struct<w,d>
	,	boost::multipliable2 < EL_Struct<w,d>, OS_double
	,   boost::dividable2 < EL_Struct<w,d>, OS_double
      > > > > //algebra is not meaningful here. It is just a code conveniency
{

public :
		typedef w										weight_set_type;
		typedef typename weight_set_type::state_variable_type	state_variable_type;
		typedef typename weight_set_type::edge_type		edge_type;
		typedef typename w::iterator					edge_iterator;
		typedef typename w::const_iterator				edge_const_iterator;
		typedef d										densities_type;
		typedef typename weight_set_type::p_array_2		particles_type;
		typedef typename weight_set_type::indice_type			indice_type;
		typedef typename particles_type::particle_type	particle_type;

		const particles_type& particles() const {return particles_;} ;
		const densities_type& densities() const {return densities_;} ;

		particles_type& particles()  {return particles_;} ;
		densities_type& densities()  {return densities_;} ;

		EL_Struct() {}; 
		EL_Struct(const EL_Struct &from) : 
			particles_(from.particles()),densities_(from.densities())
		{};
		EL_Struct(const particle_type &from) : 
			particles_(from)
		{};


		inline indice_type dim() const {
			return particles_.dim();
		}
		inline indice_type cardinal() const {
			return particles_.cardinal();
		}


		inline void my_resize(indice_type nb, indice_type dim) {
			particles_.my_resize(nb,dim);
			densities_.resize(nb);
		}



       inline const EL_Struct& operator+=(const EL_Struct &from)  {
		   densities_ += from.densities();
		   particles_ += from.particles();
		   return *this;
        };
       inline const EL_Struct& operator-=(const EL_Struct &from)  {
		   densities_ -= from.densities();
		   particles_ -= from.particles();
		   return *this;
        };
       inline const EL_Struct& operator*=(OS_double from)  {
		   densities_ *= from;
		   particles_ *= from;
		   return *this;
        };
       inline const EL_Struct& operator /=(OS_double from)  {
		   densities_ /= from;
		   particles_ /= from;
		   return *this;
        };

		particles_type particles_;
		densities_type densities_;
};





#endif